package com.ebs.md.fxmonitor.marketmonitor.config;

/**
 * Perforce Revision:
 *  $File: //depot/MarketData/fxmonitor/main/src/main/java/com/ebs/md/fxmonitor/marketmonitor/config/OutOfRegionQuotingConfigImpl.java $
 *  $Revision: #20 $  $Change: 116326 $  $DateTime: 2012/10/29 12:28:32 $  $Author: Aviad.Yosef $
 */

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.apache.log4j.Logger;

import com.ebs.md.fxmonitor.marketmonitor.MarketMonitorConsts;
import com.ebsdr.fsp.ccc.configuration.IConfiguration;


public class OutOfRegionQuotingConfigImpl 
implements IConfigListener, IOutOfRegionQuotingConfig, MarketMonitorConsts
{
    final protected Logger logger = Logger.getLogger(getClass());

	final protected static String xsdPath = "/MonitoredMarketActivity/OutOfRegionQuotingAlerts/OutOfRegionQuoting/";

    private Map<String, OutOfRegionConfigInfo> regionConfigMap; 
    
    private List<String> monitoredPairsList;
    
    
    public OutOfRegionQuotingConfigImpl()
    {
    	regionConfigMap = new HashMap<String, OutOfRegionConfigInfo>();
    }
	
	@Override
	public String getName() {
		return BASIC_CONFIG_NAME;
	}

	@Override
	public void onConfig(IConfiguration configuration) {
    	regionConfigMap.clear();

    	monitoredPairsList = configuration.getList(xsdPath + "/CurrencyPair/@name");

		for (ERegionTimeZone currRegionName: ERegionTimeZone.values()){
			OutOfRegionConfigInfo regionInfo = new OutOfRegionConfigInfo(currRegionName.getRegionName());
			
			regionInfo.onConfig(configuration);
			
			regionConfigMap.put(currRegionName.getRegionName(), regionInfo);
		}

		logger.info( getConfigInfo() );
	}

	@Override
	public String getConfigInfo() {
		String indent = "\n                              				";
		StringBuilder sb = new StringBuilder("OutOfRegionQuotingConfigImpl:");
     
		sb.append(indent + "monitoredPairsList:");
		
		for ( String currPairName : monitoredPairsList ) {
			sb.append(String.format(" '%s', ", currPairName));
		}
		
		for (ERegionTimeZone currRegion: ERegionTimeZone.values()){
			OutOfRegionConfigInfo outOfRegionConfigInfo = regionConfigMap.get(currRegion.getRegionName()); 
			
			if (outOfRegionConfigInfo != null){
				sb.append(indent + outOfRegionConfigInfo.getConfigInfo()); //print it nicely.
			}
		}		
		
		return sb.toString();
	}

	@Override
	public long getBlackoutFrom(String regionName) {
		OutOfRegionConfigInfo regionConfigInfo = regionConfigMap.get(regionName);
		
		long res = valueOfTime(EVENT_OUT_OF_REGION_QUOTING_BLACKOUT_FROM_THRESHOLD);
		
		if (regionConfigInfo != null){
			res = regionConfigInfo.blackoutFrom;
		}
		
		return res;
	}

	@Override
	public long getBlackoutTo(String regionName) 
	{
		OutOfRegionConfigInfo regionConfigInfo = regionConfigMap.get(regionName);
		
		long res = valueOfTime(EVENT_OUT_OF_REGION_QUOTING_BLACKOUT_TO_THRESHOLD);
		
		if (regionConfigInfo != null){
			res = regionConfigInfo.blackoutTo;
		}
		
		return res;
	}

	@Override
	public int getNumberOfPassiveQuotesThreshold(String regionName) 
	{
		OutOfRegionConfigInfo regionConfigInfo = regionConfigMap.get(regionName);
		int res = EVENT_OUT_OF_REGION_QUOTING_NUMBER_OF_PASSIVE_QUOTES_THRESHOLD;
		
		if (regionConfigInfo != null){
			res = regionConfigInfo.numberOfPassiveQuotesThreshold;
		}
		
		return res;
	}

	@Override
	public boolean getIsMonitored(String regionName) {
		OutOfRegionConfigInfo regionConfigInfo = regionConfigMap.get(regionName);
		boolean res = false;
		
		if (regionConfigInfo != null){
			res = regionConfigInfo.isMonitored;
		}
		
		return res;
	}

	@Override
	public List<String> getMonitoredPairsList() {
		return monitoredPairsList;
	}
    
	public class OutOfRegionConfigInfo implements IConfigListener
	{
		private String  regionName;
		private String  blackoutFromStr;
		private String  blackoutToStr;
	    private long    blackoutFrom;
	    private long    blackoutTo;
	    private int     numberOfPassiveQuotesThreshold;
	    private boolean isMonitored;
			    
	    public OutOfRegionConfigInfo(String i_regionName)
	    {
	    	regionName = i_regionName;
	    }
	    
		@Override
		public String getConfigInfo() 
		{
			StringBuilder sb = new StringBuilder("");
			sb.append(  "regionName: "                     + regionName);
			sb.append(", isMonitored: "                    + isMonitored);
			sb.append(", numberOfPassiveQuotesThreshold: " + numberOfPassiveQuotesThreshold);
			sb.append(", blackoutFrom: "                   + blackoutFromStr);
			sb.append(", blackoutTo: "                     + blackoutToStr);
			sb.append(", blackoutFromMillis: "             + blackoutFrom);
			sb.append(", blackoutToMillis: "               + blackoutTo);
			
			return sb.toString();
		}

		@Override
		public void onConfig(IConfiguration configuration) 
		{
			String path = xsdPath + regionName;
			
			blackoutFromStr                = configuration.getString (path + "/@blackoutFrom", EVENT_OUT_OF_REGION_QUOTING_BLACKOUT_FROM_THRESHOLD);
			blackoutToStr                  = configuration.getString (path + "/@blackoutTo",   EVENT_OUT_OF_REGION_QUOTING_BLACKOUT_TO_THRESHOLD);
			isMonitored                    = configuration.getBoolean(path + "/@switch",      EVENT_OUT_OF_REGION_QUOTING_IS_MONITORED_THRESHOLD);
			numberOfPassiveQuotesThreshold = configuration.getInt    (path + "/@numberOfPassiveQuotes", EVENT_OUT_OF_REGION_QUOTING_NUMBER_OF_PASSIVE_QUOTES_THRESHOLD);
			
			// we used this code in order to set the time zone by the current region.
		    // we decided not to use it and to set all time zones as GMT-0.
//			ERegionTimeZone eRegionTimeZone = ERegionTimeZone.getByName(regionName);
//			TimeZone blackoutTZ = TimeZone.getTimeZone(eRegionTimeZone.getTzName());
			
			blackoutFrom = valueOfTime(blackoutFromStr);
			blackoutTo   = valueOfTime(blackoutToStr);
		}
		
	}

	@Override
	public String getRegionAlias(String regionName) {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 *  
	 *  note: we convert the user input time "HH:MM:SS" in the user time zone to 
	 *        "HH:MM:SS" GMT-0  time zone so it will be more intuitive to work with. 
	 *        
	 *  @timeValStr - time as string format: "HH:MM:SS".
	 *  @blackoutTZ - time zone to convert the timeValStr.
	 *                if the time zone is GMT+ than we will increase the time in ms since epoc.
	 *                if the time zone is GMT- than we will decrease the time in ms since epoc.
	 *  
	 *  @return - time since epoc GMT-0 in ms.
	 */
    protected long valueOfTime(String timeValStr) {
    	SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
    	TimeZone blackoutTZ = TimeZone.getTimeZone("Etc/GMT0");
    	
    	sdf.setTimeZone(blackoutTZ);
        
		Date timeObj;
		try {
			timeObj = sdf.parse(timeValStr);
		} catch (ParseException e) {
			throw new RuntimeException("unexpected", e);
		}

		return timeObj.getTime();
    }

}
